package io.gitee.zhangbinhub.acp.boot.exceptions

import io.gitee.zhangbinhub.acp.boot.tools.PackageTools
import jakarta.validation.ConstraintViolationException
import org.springframework.beans.TypeMismatchException
import org.springframework.core.Ordered
import org.springframework.http.HttpStatus
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.MissingServletRequestParameterException
import org.springframework.web.server.ResponseStatusException

class AcpDefaultWebExceptionHandler : AcpWebExceptionHandler {
    override fun getOrder(): Int = Ordered.LOWEST_PRECEDENCE
    override fun identify(ex: Throwable?): Boolean = true
    override fun handle(ex: Throwable?): ErrorResult = when (ex) {
        // customer
        is WebException -> {
            PackageTools.buildErrorResult(ex.httpStatus, ex.message)
        }

        // validate
        is ConstraintViolationException -> {
            val errorMsg = StringBuilder()
            ex.constraintViolations.forEach { error -> errorMsg.append(error.message).append(";") }
            PackageTools.buildErrorResult(HttpStatus.BAD_REQUEST, errorMsg.toString())
        }

        // servlet
        is MethodArgumentNotValidException -> {
            val errorMsg = StringBuilder()
            ex.bindingResult.allErrors.forEach { error -> errorMsg.append(error.defaultMessage).append(";") }
            PackageTools.buildErrorResult(HttpStatus.BAD_REQUEST, errorMsg.toString())
        }

        is MissingServletRequestParameterException -> {
            PackageTools.buildErrorResult(HttpStatus.BAD_REQUEST, ex.message)
        }

        is TypeMismatchException -> {
            PackageTools.buildErrorResult(HttpStatus.BAD_REQUEST, ex.message)
        }

        // reactive
        is ResponseStatusException -> {
            PackageTools.buildErrorResult(HttpStatus.valueOf(ex.statusCode.value()), ex.reason)
        }

        else -> {
            PackageTools.buildErrorResult(HttpStatus.INTERNAL_SERVER_ERROR, ex?.message)
        }
    }
}